%include "asm_io.inc"
%define NUM_INPUTS 5

segment .data
;
;initialized data is put in the data segment here
;
	prompt1 db "Give number #", 0
	prompt2 db ":    ", 0
	label1	db "Bubblesorting as signed integers", 0
	label2	db "Bubblesorting as unsigned integers", 0
	label3	db "Order after ", 0
	label4	db " pass(es):", 0
	label5	db "Sorting complete!", 0

segment .bss
;
;uninitialized data is put in the bss segment
;
	inputs resd NUM_INPUTS

segment .text
	global asm_main
	asm_main:
	enter 0,0 ;setup routine
	pusha

	;Have user input the numbers
	mov		ecx, NUM_INPUTS ;loop counter
	inputloop:
		mov		eax, prompt1
		call	print_string
		mov		ebx, (NUM_INPUTS + 1)
		sub		ebx, ecx ;ebx = number of the current input (1..NUM_INPUTS)
		mov		eax, ebx
		call	print_int
		mov		eax, prompt2
		call	print_string
		call	read_int
		sub		ebx, 1
		mov		[inputs + ebx*4], eax
	loop	inputloop

	;perform bubblesort on numbers as signed integers
	mov		eax, label1
	call	print_string
	call	print_nl
	
	mov		ebx, 0 ;using ebx to track the number of passes so far
	mov		edx, 1 ;using edx to track whether there has been a pass with no swaps made
	bubbleloop1:

		;Output the number of passes and the current order
		mov		eax, label3
		call	print_string
		mov		eax, ebx
		call	print_int
		mov		eax, label4
		call	print_string
		call	print_nl
		mov		eax, inputs
		mov		ecx, NUM_INPUTS ;loop counter
		printloop1:
			push	eax
			mov		eax, [eax]
			call	print_int
			pop		eax
			add		eax, 4 ;next element to be outputted
			;print comma unless at last element
			cmp		ecx, 1
			je		lastelement1
				push	eax
				mov		al, ','
				call	print_char
				pop		eax
			lastelement1:
		loop	printloop1
		call	print_nl
		
		;perform one pass of bubblesort if not done
		cmp		edx, 0
		je		bubbleloop1done ;exit bubbleloop1 if no swaps were made during last pass
		mov		edx, 0 ;no swaps made yet this pass
		mov		ecx, NUM_INPUTS-1 ;loop counter
		mov		eax, inputs ;
		push	ebx ;store count of passes made so far
		bubbleloop1inner:
			mov		ebx, [eax] ;move current value into ebx
			cmp		ebx, [eax + 4] ;compare current value with next value
			jng		noswap1 ;do not swap if current value not greater than next value
				;swap current and next value, set edx to 1 to record that swap has been made
				mov	edx, [eax + 4]
				mov [eax], edx
				mov [eax + 4], ebx
				mov edx, 1
			noswap1:
			add		eax, 4 ;go to next value
		loop	bubbleloop1inner
		
		pop		ebx ;retrieve count of passes made so far
		add		ebx, 1 ;increment count of passes made so far
	jmp		bubbleloop1
	bubbleloop1done:
	
	mov eax,label5
	call print_string
	call print_nl

	;perform bubblesort on numbers as signed integers
	mov 	eax, label2
	call	print_string
	call	print_nl
	
	mov		ebx, 0 ;using ebx to track the number of passes so far
	mov		edx, 1 ;using edx to track whether there has been a pass with no swaps made
	bubbleloop2:

		;Output the number of passes and the current order
		mov		eax, label3
		call	print_string
		mov		eax, ebx
		call	print_int
		mov		eax, label4
		call	print_string
		call	print_nl
		mov		eax, inputs
		mov		ecx, NUM_INPUTS ;loop counter
		printloop2:
			push	eax
			mov		eax, [eax]
			call	print_int
			pop		eax
			add		eax, 4 ;next element to be outputted
			;print comma unless at last element
			cmp		ecx, 1
			je		lastelement2
				push	eax
				mov		al, ','
				call	print_char
				pop		eax
			lastelement2:
		loop	printloop2
		call	print_nl
		
		;perform one pass of bubblesort if not done
		cmp		edx, 0
		je		bubbleloop2done ;exit bubbleloop1 if no swaps were made during last pass
		mov		edx, 0 ;no swaps made yet this pass
		mov		ecx, NUM_INPUTS-1 ;loop counter
		mov		eax, inputs ;
		push	ebx ;store count of passes made so far
		bubbleloop2inner:
			mov		ebx, [eax] ;move current value into ebx
			cmp		ebx, [eax + 4] ;compare current value with next value
			jna		noswap2 ;do not swap if current value (unsigned) not greater than next value (unsigned)
				;swap current and next value, set edx to 1 to record that swap has been made
				mov	edx, [eax + 4]
				mov [eax], edx
				mov [eax + 4], ebx
				mov edx, 1
			noswap2:
			add		eax, 4 ;go to next value
		loop	bubbleloop2inner
		
		pop		ebx ;retrieve count of passes made so far
		add		ebx, 1 ;increment count of passes made so far
	jmp		bubbleloop2
	bubbleloop2done:
	
	mov eax,label5
	call print_string
	call print_nl
	

	popa
	mov eax,0 ;return back to C
	leave
	ret